package org.example.java.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Created by Juntao.Zhang on 2014/12/30.
 */
public class JDKReflectionUtil {
  public static Object getProperty(Object owner, String fieldName) throws Exception {
    Class ownerClass = owner.getClass();
//    Field field = ownerClass.getField(fieldName);
    Field field = ownerClass.getDeclaredField(fieldName);
    field.setAccessible(true);
    return field.get(owner);
  }

  public static Object getStaticProperty(String className, String fieldName)
      throws Exception {
    Class ownerClass = Class.forName(className);
    Field field = ownerClass.getDeclaredField(fieldName);
    field.setAccessible(true);
    return field.get(ownerClass);
  }

  public static Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {
    Class<?> ownerClass = owner.getClass();
    Class[] argsClass = new Class[args.length];
    for (int i = 0, j = args.length; i < j; i++) {
      argsClass[i] = args[i].getClass();
    }
    Method method = ownerClass.getMethod(methodName, argsClass);
    method.setAccessible(true);
    return method.invoke(owner, args);
  }


  public static Object invokeStaticMethod(String className, String methodName,
                                          Object[] args) throws Exception {
    Class<?> ownerClass = Class.forName(className);
    Class[] argsClass = new Class[args.length];
    for (int i = 0, j = args.length; i < j; i++) {
      argsClass[i] = args[i].getClass();
    }
    Method method = ownerClass.getMethod(methodName, argsClass);
    method.setAccessible(true);
    return method.invoke(null, args);
  }

  public static Object newInstance(String className, Object[] args) throws Exception {
    Class<?> ownerClass = Class.forName(className);
    Class[] argsClass = new Class[args.length];
    for (int i = 0, j = args.length; i < j; i++) {
      argsClass[i] = args[i].getClass();
    }
    Constructor cons = ownerClass.getConstructor(argsClass);
    cons.setAccessible(true);
    return cons.newInstance(args);
  }
}
